#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>

#include "datrie.h"
#include "context.h"
#include "charset.h"
#include "segger.h"
#include "mylog.h"

#define USAGE	"hiseg alpha 0.01\n"	\
				"usage:\n"				\
				"-f file -d dict\n"				\
				"-u utf8 -d dict\n"				\
				"\n"				
#define LINE_BUF_SIZE	(1024*32)

int main(int argc, char ** argv)
{
	char c = 0;
	unsigned char bline = 0;
	const char * dict_path = NULL;
	const char * dict_utf8 = NULL;
	const char * ctx_path = NULL;
	const char * nr_path = NULL;
	const char * ns_path = NULL;
	const char * tr_path = NULL;
	const char * file_path = NULL;
	while ((c = getopt(argc, argv, "f:d:c:u:r:s:t:h")) != -1) {
		switch (c) {
		case 'd':
			dict_path = optarg;
			break;
		case 'c':
			ctx_path = optarg;
			break;
		case 'r':
			nr_path = optarg;
			break;
		case 's':
			ns_path = optarg;
			break;
		case 't':
			tr_path = optarg;
			break;
		case 'f':
			file_path = optarg;
			break;
		case 'u':
			dict_utf8 = optarg;
			break;
		case 'h':
			fprintf(stdout, USAGE);
			return 0;
		default:
			fprintf(stderr, "Illegal argument \"%c\"\n", c);
			return 1;
		}
	}
	if(dict_path == NULL || (file_path == NULL && dict_utf8 == NULL)){
		fprintf(stderr, USAGE);
		return 2;
	}
	LOGON("stdout");
	int ret = 0;
	dat * datp = dat_new();
	if(datp == NULL){
		return 3;
	}
	if(dict_utf8 != NULL){
		ret = dat_dump(datp, dict_utf8, dict_path);
	}else{
		ret = dat_load(datp, dict_path);
	}
	if(ret < 0){
		fprintf(stderr, "load/dump %s err, ret=%d \n", dict_path, ret);
		return 4;
	}
	if(file_path == NULL){
		printf("gen dict\n");
		return 0;
	}
	ctx * ctxp = ctx_new();
	ret = ctx_load(ctxp, ctx_path);
	if(ret < 0){
		fprintf(stderr, "load %s err, ret=%d \n", ctx_path, ret);
		return 5;
	}
	
	ctx * nrp = NULL;
	ctx * nsp = NULL;
	ctx * trp = NULL;

	if(nr_path){
		nrp = ctx_new();
		if(nrp == NULL){
			return 6;
		}
		ret = ctx_load(nrp, nr_path);
		if(ret < 0){
			return 7;
		}
	}
	if(ns_path){
		nsp = ctx_new();
		if(nsp == NULL){
			return 8;
		}
		ret = ctx_load(nsp, ns_path);
		if(ret < 0){
			return 9;
		}
	}
	if(tr_path){
		trp = ctx_new();
		if(trp == NULL){
			return 10;
		}
		ret = ctx_load(trp, tr_path);
		if(ret < 0){
			return 11;
		}
	}
	FILE *fp = fopen(file_path, "r");
    if(fp == NULL){
		fprintf(stderr, "open %s err!\n", file_path);
        return 12;
    }
	init_codemap();
	segger * p = segger_new(datp, ctxp, nrp, nsp, trp);
	if(p == NULL){
		return 13;
	}
	char * buf = NULL;
	if(bline){
		int ret = 0;
		buf = malloc(LINE_BUF_SIZE);
		memset(buf, 0, LINE_BUF_SIZE);
		while(fgets(buf, LINE_BUF_SIZE, fp)){
			ret = segger_do(p, buf, strlen(buf));
			if(ret < 0){
				fprintf(stderr, "err: segger do %d\n", ret);
				return 14;
			}
			const char * res = NULL;
			unsigned len = 0;
			char out[1024*32] = {0};
			while((res = segger_next_res(p, &len)) != NULL){
				if(res == NULL){
					return 15;
				}
				strncpy(out, res, len);
				out[len] = 0;
	//			printf("%s ", out);
				printf(">%d:%d \n", res - buf, len);
			}
			memset(buf, 0, LINE_BUF_SIZE);
		}
        printf("\n");
	}else{
		if(fseek(fp, 0, SEEK_END) < 0){
			return 16;
		}
		unsigned size = ftell(fp);
		if(size <= 0){
			return 17;
		}
		buf = malloc(size+1);
		if(fseek(fp, 0, SEEK_SET) < 0){
			return 18;
		}
		int ret = fread(buf, size, 1, fp);
		if(ret != 1){
			fprintf(stderr, "read %u/%u\n", strlen(buf), size);
			return 19;
		}
//		printf("read %u/%u\n", strlen(buf), size);
		buf[size] = 0;
		size = strlen(buf);
		fprintf(stderr, "ready\n");
		if((ret = segger_do(p, buf, size)) < 0){
			printf("segger_do err, ret=%d\n", ret);
			return 20;
		}
		fprintf(stderr, "finish\n");
		const char * res = NULL;
        unsigned len = 0;
        char out[1024*32] = {0};
        while((res = segger_next_res(p, &len)) != NULL){
			if(res == NULL){
				return 21;
			}
            strncpy(out, res, len);
            out[len] = 0;
			printf("%s ", out);
        }

        printf("\n");
	}
	segger_free(p);
	dat_free(datp);
	free_codemap();	
	free(buf);
	fclose(fp);
	LOGOFF();
	return 0;
}
